﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using WeSTrip.model;
using System.ServiceModel.Channels;
using System.Configuration;
using WeSTrip.util;
using System.Data;
using WeSTrip.controller;

namespace WeSTrip
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class WeSTrip : IWeSTrip
    {
        private bool checkAuthenticatedIp(string iP)
        {
            
            string whiteIP = ConfigurationManager.AppSettings["WhiteIPs"];
            whiteIP = whiteIP.Trim();
            string[] result = whiteIP.Split(';');

            foreach (string sub in result)
            {
                string t = sub.Trim();
                if (iP == t)
                    return true;

            }
            return false;

        }

 
        public TripResultStatus requestIP()
        {

            OperationContext context = OperationContext.Current;
            MessageProperties messageProperties = context.IncomingMessageProperties;
            RemoteEndpointMessageProperty endpointProperty =
              messageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;


            if (!checkAuthenticatedIp(endpointProperty.Address))
            {
                return new TripResultStatus
                {
                    statusCode = TripResultStatus.STATUS_UNALLOW_IP_CODE,
                    statusText = string.Format(TripResultStatus.STATUS_UNALLOW_IP_TEXT, endpointProperty.Address)

                };

            }
            else
            {
                return new TripResultStatus
                {
                    statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                    statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                };
            }
        }
        public DataTable getNewTrips(int num)
        {
            TripResultStatus request = requestIP();
            DataTable dt= null;
            if (request.statusCode == 0)
            {
                try
                {
                    dt = DB.getData("SELECT TOP " + num + " * FROM TRIP WHERE DequeueTime is not Null ORDER BY DequeueTime DESC ;");
                    return dt;

                }
                catch (Exception ex)
                {
                    // log
                    //LogController.createLog(new Log(DateTime.Now.ToString("yyyyMMddHHmmss"), ex.Message, 1, "Error getComments"));
                    return null;
                }
            }
            else
            {
                return dt;
            }
        }
        public int getCurrentSlot(int tripId)
        {
            int slot = Convert.ToInt32(DB.getValue("select COUNT (*) AS NumberOfOrders from TRIPJOIN where TripId= " + tripId + " and IsApproved = 1 and StatusId !=0;"));
            return slot;
        }
        public WeSTripEnqueueResult enqueue(Trip trip)
        {
            TripResultStatus request = requestIP();
            if (request.statusCode == 0)
            {
                try
                {

                        object[,] parameter = { 
                                        {"@SysUserId",trip.sysUserId},
                                        {"@AddressFrom",trip.addressFrom},
                                        {"@AddressTo",trip.addressTo},
                                        {"@AvaiableSlot",trip.avaiableSlot},
                                        {"@EnqueueTime",DateTime.Now.ToString("yyyyMMddHHmmss")},
                                        {"@Comment",trip.comment},
                                        {"@DepartTime",trip.departTime},
                                        {"@PaymentMethodId",trip.paymentMethodId},
                                        {"@Price",trip.price},
                                        // {"@ScheduleId",trip.scheduleId},
                                        {"@StatusId",trip.statusId},
                                        {"@CarId",trip.carId},

                                      };

                        DB.exec("insert into TRIP (SysUserId, AddressFrom, AddressTo, AvaiableSlot, EnqueueTime, Comment, DepartTime, PaymentMethodId, Price, StatusId, SCarId) values" +
                                    " (@SysUserId, @AddressFrom, @AddressTo, @AvaiableSlot, @EnqueueTime, @Comment, @DepartTime, @PaymentMethodId, @Price, @StatusId, @CarId );", parameter);
                        string newID = DB.getValue("select IDENT_CURRENT('TRIP')");
                        foreach (Schedule item in trip.schedule )
                        {
                            object[,] parameterS ={
                                                     {"@WeekNumber", item.weekNum},
                                                     {"@Year",item.year},
                                                     {"@Monday",item.monday},
                                                     {"@Tuesday",item.tuesday},
                                                     {"@Wednesday",item.wednesday},
                                                     {"@Thursday",item.thursday},
                                                     {"@Friday",item.friday},
                                                     {"@Saturday",item.saturday},
                                                     {"@Sunday",item.sunday},
                                                     {"@TripId",newID},
                                                 };
                            DB.exec("insert into SCHEDULE (WeekNumber, Year, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, TripId) values" +
                                        " (@WeekNumber, @Year, @Monday, @Tuesday, @Wednesday, @Thursday, @Friday, @Saturday, @Sunday, @TripId);", parameterS);

                        }
                        //wakeUpWiSMsg();
                        return new WeSTripEnqueueResult
                        {
                            msgResultStatus = new TripResultStatus
                            {
                                statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                                statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                            }
                        };

                }
                catch (Exception ex)
                {
                    return new WeSTripEnqueueResult
                    {
                        msgResultStatus = new TripResultStatus
                        {
                            statusCode = 500,
                            statusText = ex.Message
                        }
                    };
                }
            }
            else
            {

                return new WeSTripEnqueueResult
                {
                    msgResultStatus = request
                };
            }
        }

        public WeSTripDequeueResult dequeue()
        {

            try
            {
                Trip tripnew = new Trip();
                DataTable dt = null;
                dt = DB.getData("select top 1 * from TRIP where DequeueTime is null");
                if (dt.Rows.Count == 0)
                {
                    return new WeSTripDequeueResult
                    {
                        trip = null,
                        msgResultStatus = new TripResultStatus
                        {
                            statusCode = TripResultStatus.STATUS_OUT_DEQUEUE_CODE,
                            statusText = TripResultStatus.STATUS_OUT_DEQUEUE_TEXT
                        }

                    };

                }
                else
                {
                    tripnew.id = Convert.ToInt32(dt.Rows[0]["Id"]);
                    tripnew.addressFrom= dt.Rows[0]["AddressFrom"].ToString();
                    tripnew.addressTo=dt.Rows[0]["AddressTo"].ToString();
                    tripnew.avaiableSlot=Convert.ToInt32(dt.Rows[0]["AvaiableSlot"]);
                    tripnew.comment=dt.Rows[0]["Comment"].ToString();
                    tripnew.departTime=dt.Rows[0]["DepartTime"].ToString();
                    tripnew.dequeueTime= DateTime.Now.ToString("yyyyMMddHHmmss");
                    tripnew.enqueueTime = dt.Rows[0]["EnqueueTime"].ToString();
                    tripnew.paymentMethodId=Convert.ToInt32(dt.Rows[0]["PaymentMethodId"]);
                    tripnew.price = Convert.ToDouble(dt.Rows[0]["Price"]);
                    //tripnew.scheduleId=Convert.ToInt32(dt.Rows[0]["ScheduleId"]);
                    tripnew.statusId=Convert.ToInt32(dt.Rows[0]["StatusId"]);
                    tripnew.sysUserId=Convert.ToInt32(dt.Rows[0]["SysUserId"]);
                    tripnew.carId = Convert.ToInt32(dt.Rows[0]["CarId"]);
                    object[,] parameter = { 
                                        {"@id",tripnew.id},
                                        {"@dequeueTime",DateTime.Now.ToString("yyyyMMddHHmmss")}
                                                       
                                      };
                    DB.exec("update TRIP Set DequeueTime =@dequeueTime where Id =@id;", parameter);
                    return new WeSTripDequeueResult
                    {
                        trip = tripnew,
                        msgResultStatus = new TripResultStatus
                        {
                            statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                            statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                        }

                    };

                }
            }
            catch (Exception ex)
            {
                return new WeSTripDequeueResult
                {
                    msgResultStatus = new TripResultStatus
                    {
                        statusCode = 500,
                        statusText = ex.Message
                    }
                };
            }
        }

      
        public TripResultStatus JoinTrip(int tripId, int guestId, string postedDate)
        {

            if (TripController.CheckSTTTrip(tripId))
            {
                if (!TripController.CheckJoinTrip(tripId, guestId))
                {
                    if (TripController.CheckAvaiable(tripId))
                    {
                        try
                        {
                            object[,] parameter = { 
                                        {"@tripId", tripId},
                                        {"@guestId", guestId},
                                        {"@postedDate", postedDate}
                                                       
                                      };
                            DB.exec("insert into TRIPJOIN (TripId, SysUserId, PostedDate, StatusId) values (@tripId, @guestId, @postedDate, 1);", parameter);
                            return new TripResultStatus
                            {
                                statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                                statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                            };
                        }
                        catch (Exception ex)
                        {
                            return new TripResultStatus
                            {
                                statusCode = 500,
                                statusText = ex.Message

                            };
                        }
                    }
                    else
                    {
                        return new TripResultStatus
                        {
                            statusCode = TripResultStatus.STATUS_FULL_SLOT,
                            statusText = TripResultStatus.STATUS_FULL_SLOT_TEXT
                        };
                    }
                }
                else
                {
                    if (TripController.CheckSTTJoinTrip(tripId, guestId))
                    {
                        if (TripController.CheckApprove(tripId, guestId))
                        {
                            return new TripResultStatus
                            {
                                statusCode = TripResultStatus.STATUS_ALREADY_JOIN,
                                statusText = TripResultStatus.STATUS_ALREADY_JOIN_TEXT
                            };
                        }
                        else
                        {
                            return new TripResultStatus
                            {
                                statusCode = TripResultStatus.STATUS_WAIT_APPROVE,
                                statusText = TripResultStatus.STATUS_WAIT_APPROVE_TEXT
                            };
                        }

                    }
                    else
                    {
                        return new TripResultStatus
                        {
                            statusCode = TripResultStatus.STATUS_NEED_REJOIN,
                            statusText = TripResultStatus.STATUS_NEED_REJOIN_TEXT
                        };
                    }
                }
            }
            else
            {
                return new TripResultStatus
                {
                    statusCode = TripResultStatus.STATUS_TRIP,
                    statusText = TripResultStatus.STATUS_TRIP_TEXT
                };
            }

           
        }
        public TripResultStatus CancelJoinTrip(int jointTripId)
        {
            SetApprove(jointTripId, 0);
            SetStatusJoinTrip(jointTripId, 0);
            
            return new TripResultStatus
            {
                statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
            };


        }
        public TripResultStatus ReJoinTrip(int tripId, int joinTripId)
        {
            if (TripController.CheckSTTTrip(tripId))
            {
                if (TripController.CheckAvaiable(tripId))
                {
                    return SetStatusJoinTrip(joinTripId, 1);

                }
                else
                {
                    return new TripResultStatus
                    {
                        statusCode = TripResultStatus.STATUS_FULL_SLOT,
                        statusText = TripResultStatus.STATUS_FULL_SLOT_TEXT
                    };
                }
            }
            else
            {
                return new TripResultStatus
                {
                    statusCode = TripResultStatus.STATUS_TRIP,
                    statusText = TripResultStatus.STATUS_TRIP_TEXT
                };
            }
        }
        public TripResultStatus CancelTrip(int tripId)
        {
            try
            {
                if (SetStatusTrip(tripId, 0).statusCode == 0)
                {
                    DataTable dt = null;
                    dt = DB.getData("select Id from TRIPJOIN where TripId = " + tripId + ";");
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        int id = Convert.ToInt32(dt.Rows[i]["Id"]);
                        SetStatusJoinTrip(id, 0);
                        SetApprove(id,0 );
                    }
                    return new TripResultStatus
                    {
                        statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                        statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                    };
                }
                else
                    return SetStatusTrip(tripId, 0);
            }
            catch (Exception ex)
            {
                return new TripResultStatus
                {
                    statusCode = 500,
                    statusText = ex.Message
                };
            }

        }
        //public TripResultStatus ReOpenTrip(int tripId)
        //{
        //    try
        //    {
        //        if (SetStatusTrip(tripId, 1).statusCode == 0)
        //        {
        //            DataTable dt = null;
        //            dt = DB.getData("select Id from TRIPJOIN where TripId = " + tripId + ";");
        //            for (int i = 0; i < dt.Rows.Count; i++)
        //            {
        //                int id = Convert.ToInt32(dt.Rows[i]["Id"]);
        //                SetStatusJoinTrip(id, 1);
        //            }
        //            return new TripResultStatus
        //            {
        //                statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
        //                statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
        //            };
        //        }
        //        else
        //            return SetStatusTrip(tripId, 1);
        //    }
        //    catch (Exception ex)
        //    {
        //        return new TripResultStatus
        //        {
        //            statusCode = 500,
        //            statusText = ex.Message
        //        };
        //    }
        //}
        public TripResultStatus SetApprove(int tripJoinId, int approve)
        {
            if (TripController.CheckSTTJoinTrip(tripJoinId))
            {
                try
                {
                    DB.exec("update TRIPJOIN Set IsApproved = " + approve + " where Id = " + tripJoinId + " ;");
                    return new TripResultStatus
                    {
                        statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                        statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                    };
                }
                catch (Exception ex)
                {
                    return new TripResultStatus
                    {
                        statusCode = 500,
                        statusText = ex.Message
                    };
                }
            }
            else
            {
                return new TripResultStatus
                {
                    statusCode = TripResultStatus.STATUS_JOIN_TRIP,
                    statusText = TripResultStatus.STATUS_JOIN_TRIP_TEXT
                };
            }

        }
        public TripResultStatus SetStatusTrip(int tripId, int statusId)
        {
            try
            {

                DB.exec("update TRIP Set StatusID = " + statusId + " where Id = " + tripId + " ;");
                return new TripResultStatus
                {
                    statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                    statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                };
            }
            catch (Exception ex)
            {
                return new TripResultStatus
                {
                    statusCode = 500,
                    statusText = ex.Message
                };
            }
        }
        public TripResultStatus SetStatusJoinTrip(int joinTripId, int statusId)
        {
            try
            {
                string query = "update TRIPJOIN Set StatusID = " + statusId + " where Id = " + joinTripId + " ;";
                DB.exec(query);
                return new TripResultStatus
                {
                    statusCode = TripResultStatus.STATUS_VALID_TOKEN_CODE,
                    statusText = TripResultStatus.STATUS_VALID_TOKEN_TEXT
                };
            }
            catch (Exception ex)
            {
                return new TripResultStatus
                {
                    statusCode = 500,
                    statusText = ex.Message
                };
            }
        }


    }
}
